using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.IO;
using Lang = CommonGenerator.Language;

namespace CommonGenerator
{
	public class CommonGeneratorTask<T> : Task where T : CommonGenerator
	{
		[Required]
		public ITaskItem GeneratedFile
		{
			get;
			set;
		}

		[Required]
		public String Language
		{
			get;
			set;
		}

		[Required]
		public ITaskItem ConfigFile
		{
			get;
			set;
		}

		[Required]
		public String Namespace
		{
			get;
			set;
		}

		[Required]
		public String ClassName
		{
			get;
			set;
		}


		protected virtual T CreateGenerator()
		{
			return (T)typeof(T).Assembly.CreateInstance(typeof(T).FullName);
		}

		protected virtual void Configure(T gen)
		{
			gen.ConfigFile = ConfigFile.ItemSpec;
			gen.Language = GetLanguage().Value;
			gen.NameSpace = Namespace;
			gen.ClassName = ClassName;
		}

		protected Language? GetLanguage()
		{
			if("C#".Equals(Language, StringComparison.InvariantCultureIgnoreCase))
				return Lang.CSharp;
			if("VB".Equals(Language, StringComparison.InvariantCultureIgnoreCase))
				return Lang.VB;
			return null;
		}

		public override bool Execute()
		{
			var language = GetLanguage();
			if(language == null)
			{
				Error(Language + " is not a valid language, specify CS or VB");
				return false;
			}
			try
			{
				string text = File.ReadAllText(ConfigFile.ItemSpec);
			}
			catch(IOException ex)
			{
				Error("Error when trying to open config file : " + " " + ConfigFile.ItemSpec + " " + ex.Message);
				return false;
			}
			try
			{
				using(var generatedWriter = new StreamWriter(File.Open(GeneratedFile.ItemSpec, FileMode.Create)))
				{
					T gen = CreateGenerator();
					Configure(gen);
					gen.WriteClass(generatedWriter);
					generatedWriter.Flush();
				}
			}
			catch(IOException ex)
			{
				Error("Error when accessing to " + GeneratedFile.ItemSpec + " " + ex.Message);
				return false;
			}
			return true;
		}

		public void Error(string message)
		{
			Log.LogError(message);
		}
	}
}
